package com.chukun.gateway.core.limiter;

import com.chukun.gateway.common.rule.Rule;
import com.google.common.util.concurrent.RateLimiter;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author chukun
 * @version 1.0.0
 * @description 基于guava单机限流
 * @createTime 2023/12/10 21:02
 */
public class GuavaCountLimiter {

    private RateLimiter rateLimiter;

    private final double maxPermits;

    private static Map<String, GuavaCountLimiter> resourceRateLimiters = new ConcurrentHashMap<>();

    public GuavaCountLimiter(double maxPermits) {
        this.maxPermits = maxPermits;
        rateLimiter = RateLimiter.create(maxPermits);
    }

    public GuavaCountLimiter(double maxPermits,long warmUpPeriodAsSecond) {
        this.maxPermits = maxPermits;
        rateLimiter = RateLimiter.create(maxPermits,warmUpPeriodAsSecond, TimeUnit.SECONDS);
    }

    public static GuavaCountLimiter getInstance(String serviceId , Rule.FlowControlConfig flowCtlConfig) {
        if(StringUtils.isEmpty(serviceId) || flowCtlConfig ==null ||
                StringUtils.isEmpty(flowCtlConfig.getValue()) ||
                StringUtils.isEmpty(flowCtlConfig.getConfig()) ||
                StringUtils.isEmpty(flowCtlConfig.getType())){
            return null;
        }
        String key = String.format("%s.%s", serviceId, flowCtlConfig.getValue());
        GuavaCountLimiter countLimiter = resourceRateLimiters.get(key);
        if(countLimiter == null){
            countLimiter = new GuavaCountLimiter(50);
            resourceRateLimiters.putIfAbsent(key,countLimiter);
        }
        return countLimiter;
    }

    /**
     *
     * @param permits 凭证
     * @return 是否可以获取单机的许可
     */
    public boolean acquire(int permits){
        return rateLimiter.tryAcquire(permits);
    }


}
